package com.idanchuang.count.dao.impl;

import com.idanchuang.count.core.domain.AnalyzeCounter;
import com.idanchuang.count.dao.CounterAnalyzeDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * @author Richard_yyf
 * @version 1.0 2021/10/12
 */
@Slf4j
public class CounterAnalyzeDaoImpl implements CounterAnalyzeDao, InitializingBean {

    private final DataSource dataSource;

    public CounterAnalyzeDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initDbIfNotExist();
        log.info("initDb success");
        initSuperTableIfNotExist();
        log.info("initSuperTable success");
    }

    private void initDbIfNotExist() {
        execute("create database if not exists simple_count keep 365");
    }

    private void initSuperTableIfNotExist() {
        String sql = "create table if not exists simple_count.counter(ts timestamp, increment bigint) tags(bizCode nchar(64), bizNo nchar(64))";
        execute(sql);
    }

    @Override
    public int insert2TablesAndAutoCreateTableWhenNotExist(List<AnalyzeCounter> counterRecords) {
        String sql = buildSqlForInsert2TablesAndAutoCreateTableWhenNotExist(counterRecords);
        return executeUpdate(sql);
    }

    private String buildSqlForInsert2TablesAndAutoCreateTableWhenNotExist(List<AnalyzeCounter> counterRecords) {

        // insert into simple_count.${bizCode}_${bizNo} using simple_count.counter TAGS ('${bizCode}', '${bizNo}') values (#ts, #increment)
        //            simple_count.${bizCode}_${bizNo} using simple_count.counter TAGS ('${bizCode}', '${bizNo}') values (#ts, #increment)
        //            simple_count.${bizCode}_${bizNo} using simple_count.counter TAGS ('${bizCode}', '${bizNo}') values (#ts, #increment);


        StringBuilder builder = new StringBuilder("insert into ");
        for (AnalyzeCounter record : counterRecords) {
            builder.append("simple_count.")
                    // simple_count.${bizCode}_${bizNo}
                    .append(record.getBizCode()).append("_").append(record.getBizNo())
                    .append(" using simple_count.counter TAGS ('")
                    // '${bizCode}', '${bizNo}'
                    .append(record.getBizCode()).append("', '").append(record.getBizNo())
                    //  (#ts, #increment)
                    .append("') values (").append(record.getTs()).append(", ").append(record.getIncrement()).append(") ");
        }
        return builder.toString();
    }

    private boolean execute(String sql) {
        try (Connection conn = dataSource.getConnection();
             Statement statement = conn.createStatement()) {

            return statement.execute(sql);

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    private int executeUpdate(String sql) {
        try (Connection conn = dataSource.getConnection();
             Statement statement = conn.createStatement()) {

            return statement.executeUpdate(sql);

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
